package com;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * 在纯粹的servlet环境下，完全不用spring，spring mvc，比如
 * 你写下面的形式的servlet
 *
 * @WebServlet("/index") public class FirstServlet extends HttpServlet {
 * void service(HttpServletRequest req,HttpServletResponse resp){
 * <p>
 * }
 * }
 * @WebServlet("/index2") * public class FirstServlet extends HttpServlet {
 * *     void service(HttpServletRequest req,HttpServletResponse resp){
 * *
 * *     }
 * * }
 * 不管请求/index1还是请求/index2,两者的req的hashcode是一模一样
 * ，基本可以认为他们是同一个对象
 * 结论：每次请求过来，HttpServletRequest对象只有一个。
 * 那为什么数据是对的（指的是从请求对象获取数据，比如req.getRequestURI()
 * <p>
 * 原因：
 * 1.整个项目第一次请求，创建一个对象
 * 放入到一个叫notes【32】数组中缓存起来
 * 2.那么每次请求，就从notes中取
 * 3.每次请求进行解析，然后把解析的结果全部填充到req对象中
 * 4.最后就交给我们的servlet使用
 */
@Controller
public class RequestTestController implements InitializingBean {
    //这个不报错，完全可以使用，也没有线程安全的问题
    // 下面的request对象注入的是一个代理对象
    // 当你真正用此对象时，会利用RequestContextHolder来获取
    // 保存在ThreadLocal中的真正的请求对象,也就是本次请求的对象

    // 那么此请求对象是什么时候保存的？请求发起时，mvc框架就把当前的请求
    //对象放到ThreadLocal
    @Autowired()
    private HttpServletRequest request;

    @RequestMapping("/index1")
    public String index1(HttpServletRequest request1) {

        System.out.println("==================");
        System.out.println(request1.getRequestURI());
        System.out.println(request1.hashCode());
        System.out.println(request1.getClass().getName());
        System.out.println(AopUtils.isAopProxy(request1));
        System.out.println("*************************");
        System.out.println(request.hashCode());

        System.out.println(request.getClass().getName());
        return "index";
    }

    @RequestMapping("/index2")
    public String index2(HttpServletRequest request2) {
        System.out.println("==================");
        System.out.println(request2.getRequestURI());
        System.out.println(request2.hashCode());
        System.out.println(request2.getClass().getName());
        System.out.println(AopUtils.isAopProxy(request2));
        System.out.println("*************************");
        System.out.println(request.hashCode());
        System.out.println(request.getClass().getName());
        return "index";
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("==================");
        System.out.println(request.hashCode());
        System.out.println(request.getClass().getName());

        System.out.println("==================");
        /*Class<? extends HttpServletRequest> aClass = request.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field.getName());
        }

        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            Parameter[] parameters = constructor.getParameters();
            for (Parameter parameter : parameters) {
                System.out.println(parameter.getName() + "--" + parameter.getType());
            }
        }*/
    }
}
